package com.zlsy.thread.lock;


import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author zhouliang
 * @date 2020/9/8 20:39
 * 用condition实现生产者和消费者模型
 */
public class ConditionDemo1 {
    private int queueSize = 10;
    private PriorityBlockingQueue<Integer> queue = new PriorityBlockingQueue<>(queueSize);
    private Lock lock = new ReentrantLock();
    private Condition notFull = lock.newCondition();
    private Condition notEmpty = lock.newCondition();

    public static void main(String[] args) {
        ConditionDemo1 conditionDemo1 = new ConditionDemo1();
        Consumer consumer = conditionDemo1.new Consumer();
        Producer producer = conditionDemo1.new Producer();
        consumer.start();
        producer.start();
    }

    class Consumer extends Thread {
        @Override
        public void run() {
            consume();
        }

        private void consume() {
            while (true) {
                lock.lock();
                try {
                    //当队列的长度为0的时候，说明队列空的，需要生产者进行生产
                    while (queue.size() == 0) {
                        System.out.println("队列空了，等待数据。");
                        try {
                            //消费者的锁进入等待
                            notEmpty.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    //队列里面有数据就取出来
                    queue.poll();
                    //唤醒生产者进行生产
                    notFull.signal();
                    System.out.println("从队列里面取走了数据，队列剩余：" + queue.size() + "个元素。");
                } finally {
                    lock.unlock();
                }
            }
        }
    }

    class Producer extends Thread {
        @Override
        public void run() {
            produce();
        }

        private void produce() {
            while (true) {
                lock.lock();
                try {
                    //如果队列满了就不生产了
                    while (queue.size() == queueSize) {
                        System.out.println("队列满了，等待消费。");
                        try {
                            notFull.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    queue.offer(1);
                    notEmpty.signalAll();
                    System.out.println("向队列插入了一个元素，队列剩余空间" + (queueSize - queue.size()) + "个元素。");
                } finally {
                    lock.unlock();
                }
            }
        }
    }
}
